package com.han.lianxi.test;

import java.io.*;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.sql.Timestamp;

public class CustomBinaryGen {
    //1G = 1024MB = 1024*1024KB = 1024*1024*1024B
    /* win10 系统显示文件夹大小最小单位是 KB */
    public static int size_1B = 1;
    public static long size_1KB = 1024 * size_1B;  //byte 最小 1KB
    public static long size_1MB = 1024 * size_1KB;
    public static long size_1GB = 1024 * size_1MB; //1073741824B = 1048576KB


    public static String util_files = "./utils_files/bin_test.bin";
    public static byte[] rdata = { 1, 0, 1, 0, 1, 0, 1, 0 };
    public static int times = 20;
    public static long file_size = size_1GB * 2;  //生成6GB的文件,需要半个多小时


    /**
     * 自定义二进制生成器  bin文件
     */
    public static void test_output_stream(long file_size) throws IOException {
        File file = new File(util_files);

        if(!file.exists()) {
            file.createNewFile();
        }

        // rdata
        long rlen = rdata.length;
        long clen_1 = file_size  / rlen;
        long clen_2 = file_size  % rlen;
        long clen = clen_2 == 0 ? clen_1 : clen_1 + 1;
        System.out.println("rlen: "+ rlen + "; filesize: " + file_size + "B; times: "+ clen);
        OutputStream os = new FileOutputStream(file);
        for (long i = 0; i < clen; i++) {
            os.write(rdata);
        }
        os.flush();
        os.close();
    }

    /** 文件映射 */
    public static void test_file_mmap_stream(long file_size) throws IOException {
        File file = new File(util_files);

        if(!file.exists()) {
            file.createNewFile();
        }
        // rdata
        int rlen = rdata.length;
        long clen_1 = file_size  / rlen;
        long clen_2 = file_size  % rlen;
        long clen = clen_2 == 0 ? clen_1 : clen_1 + 1;
        System.out.println("rlen: "+ rlen + "; filesize: " + file_size + "B; times: "+ clen);

        RandomAccessFile acf = new RandomAccessFile(file, "rw");
        FileChannel fc = acf.getChannel();
        //映射到内存 1MB
        int sizePage = 1 * 1024 * 1024; //1 MB
        int sumPage = (int) (file_size/sizePage); //总共映射多少页
        MappedByteBuffer mbuf = null;
        for (int i = 0; i < sumPage; i++) {
//            System.out.println("第" + (i + 1) + "次");    //1024*1024*1*2049
            mbuf = fc.map(FileChannel.MapMode.READ_WRITE, i * sizePage, sizePage);
            for(int j = 0; j < sizePage*1024*1024/rlen; j++) {
                mbuf.put(rdata);
            }
        }
        if(null != mbuf) {
            mbuf.clear();
        }
        fc.close();
        acf.close();
    }
    public static void test_write_effic() throws IOException {
        Timestamp startTime = new Timestamp(System.currentTimeMillis());
        test_file_mmap_stream(file_size);
//        test_output_stream(file_size);
        Timestamp endTime = new Timestamp(System.currentTimeMillis());
        System.out.println("开始时间： " + startTime.getTime() + "  -> " + startTime.toString());
        System.out.println("开始时间： " + endTime.getTime() + "  -> " + endTime.toString());
        System.out.println("用时 " + ((endTime.getTime() - startTime.getTime())/1000) + "s");
    }
    public static void test_read() throws IOException{
        File file = new File(util_files);

        if(!file.exists()) {
            throw new Error("文件不存在");
        }
        InputStream in = new FileInputStream(file);

        byte []data = new byte[1024];
        for (int i = 0; i < 5; i++) {
            in.read(data, 0, 1024);
            System.out.println();
            for (int j = 0; j < 1024; j++) {
                System.out.print(" " + data[j]);
            }
        }
        in.close();
    }

    public static void main(String[] args) throws IOException {
//        System.out.println((long)(1024*1024*1024) - 0x7FFFFFFF);
//        System.out.println(Integer.MAX_VALUE);
//        System.out.println(0x7FFFFFFF);
//        System.out.println(1024*1024);
        test_write_effic();
//        test_read();
    }

}
